package cn.sumpu.app.coolsk.biz.impl;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import cn.sumpu.app.coolsk.biz.FaxBiz;
import cn.sumpu.app.coolsk.biz.HotelRoomBiz;
import cn.sumpu.app.coolsk.biz.OrderBiz;
import cn.sumpu.app.coolsk.biz.WeiboBiz;
import cn.sumpu.app.coolsk.constant.PageSize;
import cn.sumpu.app.coolsk.constant.Table;
import cn.sumpu.app.coolsk.constant.UserType;
import cn.sumpu.app.coolsk.dao.HotelRoomDao;
import cn.sumpu.app.coolsk.domain.Hotel;
import cn.sumpu.app.coolsk.domain.Order;
import cn.sumpu.app.coolsk.domain.OrderProduct;
import cn.sumpu.app.coolsk.domain.Room;
import cn.sumpu.app.coolsk.domain.RoomPrice;
import cn.sumpu.app.coolsk.exception.AppBusinessException;
import cn.sumpu.toolkit.common.page.PageModel;
import cn.sumpu.toolkit.common.util.Common;
import cn.sumpu.toolkit.common.util.Encode;

public class HotelRoomBizImpl implements HotelRoomBiz {

    private final static Logger          logger = LoggerFactory.getLogger(HotelRoomBizImpl.class);

    @Autowired
    private HotelRoomDao                 hotelRoomDao;
    @Autowired
    private OrderBiz                     orderBiz;
    @Autowired
    private FaxBiz                       faxBiz;
    private String                       webServer;
    private Calendar                     cal    = Calendar.getInstance();
    private DataSourceTransactionManager transactionManager;

    public void setWebServer(String webServer) {
        this.webServer = webServer;
    }

    public void setHotelRoomDao(HotelRoomDao hotelRoomDao) {
        this.hotelRoomDao = hotelRoomDao;
    }

    public void setTransactionManager(DataSourceTransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

    @Autowired
    private IdentifierBizImpl identifierBiz;
    @Autowired
    private WeiboBiz          weiboBiz;

    @Override
    public Hotel saveHotel(Hotel hotel) throws AppBusinessException {
        if (hotel != null) {
            if (Common.empty(hotel.getId())) {
                hotel.setId(identifierBiz.generateId(Table.HOTEL));
                hotelRoomDao.insertHotel(hotel);
            } else {
                hotelRoomDao.updateHotel(hotel);
            }
        }
        return hotel;
    }

    @Override
    public Room saveRoom(Room room) throws AppBusinessException {
        if (room != null) {
            if (Common.empty(room.getId())) {
                room.setId(identifierBiz.generateId(Table.ROOM));
                hotelRoomDao.insertRoom(room);
            } else {
                hotelRoomDao.updateRoom(room);
            }
        }
        return room;
    }

    @Override
    public Hotel getHotelById(String id) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", id);
        List<Hotel> list = hotelRoomDao.getHotel(map);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public Hotel delHotelById(String id) throws AppBusinessException {
        Hotel hotel = getHotelById(id);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", id);
        hotelRoomDao.delHotel(map);
        return hotel;
    }

    @Override
    public Room delRoomById(String id) throws AppBusinessException {
        Room room = getRoomById(id);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", id);
        hotelRoomDao.delRoom(map);
        return room;
    }

    @Override
    public List<Room> getHotelRoom(String hotelId) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("hotel", hotelId);
        List<Room> list = hotelRoomDao.getRoom(map);
        return list;
    }

    @Override
    public PageModel getHotelRoom(Integer page, Integer pagesize, String name, String hotelId) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        page = page == null ? 1 : page;
        pagesize = pagesize == null ? 10 : pagesize;
        int size = pagesize;
        map.put("startId", (page - 1) * size);
        map.put("pageSize", size);
        map.put("hotel", hotelId);
        if (!Common.empty(name)) {
            map.put("name", "%" + name + "%");
        }
        int count = hotelRoomDao.getRoomCount(map);
        PageModel pm = new PageModel();
        pm.setCurrentPage(page);
        pm.setList(hotelRoomDao.getRoom(map));
        pm.setPageSize(size);
        pm.setTotalRecord(count);
        pm.setTotalPage((count + size - 1) / size);
        return pm;
    }

    @Override
    public PageModel getHotelList(Integer page, Integer pagesize, String name) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        page = page == null ? 1 : page;
        pagesize = pagesize == null ? 10 : pagesize;
        int size = pagesize;
        map.put("startId", (page - 1) * size);
        map.put("pageSize", size);
        if (!Common.empty(name)) {
            map.put("name", "%" + name + "%");
        }
        int count = hotelRoomDao.getHotelCount(map);
        PageModel pm = new PageModel();
        pm.setCurrentPage(page);
        pm.setList(hotelRoomDao.getHotel(map));
        pm.setPageSize(size);
        pm.setTotalRecord(count);
        pm.setTotalPage((count + size - 1) / size);
        return pm;
    }

    @Override
    public void saveRoom(String hotelId, String rList) throws AppBusinessException {
        try {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("hotel", hotelId);
            hotelRoomDao.delRoom(map);
            JSONArray list = JSONArray.fromObject(Encode.unescape(rList));
            for (Object object : list) {
                Room room = (Room) JSONObject.toBean((JSONObject) object, Room.class);
                room.setId(identifierBiz.generateId(Table.ROOM));
                hotelRoomDao.insertRoom(room);
            }
        } catch (Exception e) {
            throw new AppBusinessException(e);
        }

    }

    @Override
    public void saveRoomPrice(String roomId, String rpList) throws AppBusinessException {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();// 事务定义类
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);// 设置事务传播属性
        TransactionStatus status = transactionManager.getTransaction(def);// 返回事务对象
        try {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("roomId", roomId);
            hotelRoomDao.delRoomPrice(map);
            JSONArray list = JSONArray.fromObject(Encode.unescape(rpList));
            for (Object object : list) {
                RoomPrice rp = (RoomPrice) JSONObject.toBean((JSONObject) object, RoomPrice.class);
                hotelRoomDao.insertRoomPrice(rp);
            }
            transactionManager.commit(status);// 提交事务
        } catch (Exception e) {
            transactionManager.rollback(status);// 回滚事务
            throw new AppBusinessException(e);
        }

    }

    @Override
    public String shareHotel(String hotelId, String weiboType) throws AppBusinessException {
        Hotel hotel = getHotelById(hotelId);
        String text = hotel.getName() + "_" + hotel.getName() + "预定,酒店查询-酷爽客酒店预订";
        try {
            text = URLEncoder.encode(text, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String url = webServer + "hotel.htm?id=" + hotelId;
        String site = "http://www.coolgy.com/";
        String picUrl = hotel.getImage1();
        String openUrl = "";
        if (weiboType.equals(UserType.SINA_WEIBO.getValue())) {
            openUrl = weiboBiz.shareSina(text, url, picUrl, site);
        } else if (weiboType.equals(UserType.TENCENT_WEIBO.getValue())) {
            openUrl = weiboBiz.shareTencent(text, url, picUrl, site);
        }
        return openUrl;
    }

    @Override
    public Room getRoomById(String id) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", id);
        List<Room> list = hotelRoomDao.getRoom(map);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public List<RoomPrice> getRoomPrice(String roomId) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("roomId", roomId);
        List<RoomPrice> rpList = hotelRoomDao.getRoomPrice(map);
        return rpList;
    }

    @Override
    public List<RoomPrice> resRoomPriceList(String roomId) throws AppBusinessException {
        Room room = getRoomById(roomId);
        if (room == null)
            return null;
        List<RoomPrice> resPriceList = new ArrayList<RoomPrice>();

        List<RoomPrice> tpList = getRoomPrice(roomId);
        int befores = room.getBefores();
        Date startDate = Common.addDate(new Date(), befores);
        cal.setTime(startDate);
        int weekday = cal.get(Calendar.DAY_OF_WEEK);
        for (int i = 0; i < weekday - 1; i++) {
            Date prevDate = Common.addDate(startDate, -weekday + i + 1);
            RoomPrice tp = new RoomPrice();
            tp.setPriceComHas(room.getPriceComHas());
            tp.setSpDate(Common.getFormatDate(prevDate, "yyyy-MM-dd"));
            resPriceList.add(tp);
        }

        for (int i = 0; i < 43 - weekday; i++) {
            RoomPrice tp = new RoomPrice();
            Date spDate = Common.addDate(startDate, i);
            String tmpDate = Common.getFormatDate(spDate, "yyyy-MM-dd");
            tp.setSpDate(tmpDate);
            tp.setPriceA(room.getPriceMin());
            tp.setPriceComHas(room.getPriceComHas());
            for (RoomPrice roomPrice : tpList) {
                String spDate1 = roomPrice.getSpDate();
                if (tmpDate.equals(spDate1)) {
                    tp = roomPrice;
                    tp.setPriceComHas(true);
                    break;
                }
            }
            resPriceList.add(tp);
        }

        cal.add(Calendar.MONTH, 1);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        weekday = cal.get(Calendar.DAY_OF_WEEK);
        for (int i = 0; i < weekday - 1; i++) {
            Date prevDate = Common.addDate(cal.getTime(), -weekday + i + 1);
            String tmpDate = Common.getFormatDate(prevDate, "yyyy-MM-dd");
            RoomPrice tp = new RoomPrice();
            tp.setPriceA(room.getPriceMin());
            tp.setSpDate(tmpDate);
            tp.setPriceComHas(room.getPriceComHas());
            for (RoomPrice roomPrice : tpList) {
                String spDate1 = roomPrice.getSpDate();
                if (tmpDate.equals(spDate1)) {
                    tp = roomPrice;
                    tp.setPriceComHas(true);
                    break;
                }
            }
            resPriceList.add(tp);
        }

        for (int i = 0; i < 43 - weekday; i++) {
            RoomPrice tp = new RoomPrice();
            Date spDate = Common.addDate(cal.getTime(), i);
            String tmpDate = Common.getFormatDate(spDate, "yyyy-MM-dd");
            tp.setSpDate(tmpDate);
            tp.setPriceA(room.getPriceMin());
            tp.setPriceComHas(room.getPriceComHas());
            for (RoomPrice roomPrice : tpList) {
                String spDate1 = roomPrice.getSpDate();
                if (tmpDate.equals(spDate1)) {
                    tp = roomPrice;
                    tp.setPriceComHas(true);
                    break;
                }
            }
            resPriceList.add(tp);
        }

        return resPriceList;
    }

    @Override
    public RoomPrice getRoomDayPrice(Room room, String date) throws AppBusinessException {
        if (room == null)
            return null;
        String now = null;
        RoomPrice dayPrice = new RoomPrice();
        int befores = room.getBefores();
        Date startDate = Common.addDate(new Date(), befores);
        if (Common.empty(date)) {
            now = Common.getFormatDate(startDate, "yyyy-MM-dd");
        } else {
            now = date;
        }
        dayPrice.setPriceA(room.getPriceMin());
        dayPrice.setSpDate(now);
        List<RoomPrice> rpList = getRoomPrice(room.getId());
        if (rpList != null && rpList.size() > 0) {
            for (RoomPrice roomPrice : rpList) {
                String spDate = roomPrice.getSpDate();
                if (now.equals(spDate)) {
                    dayPrice = roomPrice;
                    break;
                }
            }
        }
        return dayPrice;
    }

    @Override
    public void sendHotelFax(String orderId) {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();// 事务定义类
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);// 设置事务传播属性
        TransactionStatus status = transactionManager.getTransaction(def);// 返回事务对象
        try {
            Order order = orderBiz.getOrderById(orderId);
            List<OrderProduct> opList = orderBiz.getOpList(orderId);
            order.setOpList(opList);
            Room room = getRoomById(opList.get(0).getPid());
            Hotel hotel = getHotelById(room.getHotel());
            String content = "Form：贵州爽爽网络传媒股份有限公司 to：" + hotel.getName() + " sub：酒店预订\r\n\r\n" + "***************订单号：" + orderId + "****************\r\n"
                             + "预定人：" + order.getContactor() + "\r\n预定详情：" + order.getOrderDetail() + "订单状态：" + order.getStatusName() + "\r\n订单数量："
                             + order.getTotalAmount() + "\r\n订单总额：" + order.getTotalFee() + "\r\n入住时间：" + order.getOrderTime() + "\r\n离店日期：" + order.getLdate()
                             + "\r\n联系电话：" + order.getPhone();
            content = content.replaceAll("<br>", "\r\n");
            faxBiz.send(content, hotel.getFax(), hotel.getName(), "酒店预定");

            transactionManager.commit(status);// 提交事务
        } catch (AppBusinessException e) {
            transactionManager.rollback(status);// 回滚事务
            e.printStackTrace();
            if (logger.isErrorEnabled()) {
                logger.error("sendHotelFax failure.", e);
            }
        }

    }

    @Override
    public PageModel getHotelList(Integer page, Integer pagesize, String name, String city) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        int size = pagesize;
        page = page == null ? 1 : page;
        map.put("startId", (page - 1) * size);
        map.put("pageSize", size);
        map.put("condition", "star");
        map.put("sort", "asc");
        if (!Common.empty(name)) {
            map.put("name", "%" + name + "%");
        }
        if (!Common.empty(city)) {
            map.put("city", city);
        }
        int count = hotelRoomDao.getHotelCount(map);
        PageModel pm = new PageModel();
        pm.setCurrentPage(page);
        pm.setList(hotelRoomDao.getHotel(map));
        pm.setPageSize(size);
        pm.setTotalRecord(count);
        pm.setTotalPage((count + size - 1) / size);
        return pm;
    }

    @Override
    public PageModel searchHotel(Integer page, String city, String name, Integer level, String priceRange, String sort) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        int size = PageSize.PAGE_SIZE_SEARCH;
        page = page == null ? 1 : page;
        map.put("startId", (page - 1) * size);
        map.put("pageSize", size);
        //AddressCode addr = addressCodeBiz.getCityCodeByName(city);
        if (!Common.empty(city)) {
            map.put("addr", "'%" + city + "%'");
        }
        if (!Common.empty(name)) {
            if (!name.equals("中文/拼音")) {
                map.put("name", "%" + name + "%");
            }
        }
        if (!Common.empty(level)) {
            map.put("star", level);
        }
        if (!Common.empty(priceRange)) {
            map.put("minPrice", getStringNum(priceRange).get("minPrice"));
            map.put("maxPrice", getStringNum(priceRange).get("maxPrice"));
        }
        setSortMap(sort, map);
        int count = hotelRoomDao.searchHotelCount(map);
        List<Hotel> list = hotelRoomDao.searchHotel(map);
        PageModel pm = new PageModel();
        pm.setCurrentPage(page);
        pm.setList(list);
        pm.setPageSize(size);
        pm.setTotalRecord(count);
        pm.setTotalPage((count + size - 1) / size);
        return pm;
    }

    public Map<String, Double> getStringNum(String s) {
        Map<String, Double> map = new HashMap<String, Double>();
        if (s != null) {
            String[] strArr = s.split("-");
            for (int i = 0; i < strArr.length; i++) {
                double d = Double.parseDouble(strArr[i]);
                if (i == 0) {
                    map.put("minPrice", d);
                } else {
                    map.put("maxPrice", d);
                }
            }
        }
        return map;
    }

    public void setSortMap(String s, Map<String, Object> map) {
        if (s != null) {
            String[] strArr = s.split("_");
            if (strArr != null && strArr.length > 1) {
                String con = strArr[0];
                if (con.equals("price")) {
                    map.put("condition", "minPrice");
                } else if (con.equals("level")) {
                    map.put("condition", "star");

                }
                map.put("sort", strArr[1]);
            }
        } else {
            map.put("condition", "minPrice");
            map.put("sort", "asc");
        }
    }

    @Override
    public List<Hotel> getHotel(Map<String, Object> map) throws AppBusinessException {

        return hotelRoomDao.getHotel(map);
    }
}
